﻿﻿using jiuyuan.数据.共享类;
using jiuyuan.数据.基础数据类;
using jiuyuan.服务;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace jiuyuan.管理器;

public class 技能管理器
{
    private readonly IServiceProvider _服务提供者;
    private readonly 效果管理器 _效果管理器;
    private readonly Dictionary<string, 技能配置> _技能配置字典 = [];
    private readonly Dictionary<Guid, 技能效果> _效果字典 = [];

    public 技能管理器(IServiceProvider 服务提供者, 效果管理器 效果管理器)
    {
        _服务提供者 = 服务提供者;
        _效果管理器 = 效果管理器;
    }

    /// <summary>
    /// 注册技能配置
    /// </summary>
    public void 注册技能(技能配置 技能配置)
    {
        _技能配置字典[技能配置.名称] = 技能配置;
    }

    /// <summary>
    /// 注册技能效果
    /// </summary>
    public void 注册效果(技能效果 效果)
    {
        _效果字典[效果.Id] = 效果;
    }

    /// <summary>
    /// 根据名称获取技能配置
    /// </summary>
    public 技能配置? 获取技能配置(string 技能名称)
    {
        return _技能配置字典.TryGetValue(技能名称, out var 配置) ? 配置 : null;
    }

    /// <summary>
    /// 根据ID获取技能效果
    /// </summary>
    public 技能效果? 获取效果(Guid 效果ID)
    {
        // 首先从本地字典查找
        if (_效果字典.TryGetValue(效果ID, out var 效果))
        {
            return 效果;
        }
        
        // 如果本地没有，从效果管理器获取
        return _效果管理器.获取效果(效果ID);
    }

    /// <summary>
    /// 加载技能的效果列表
    /// </summary>
    public void 加载技能效果(技能配置 技能)
    {
        技能.效果列表.Clear();
        foreach (var 效果ID in 技能.效果ID列表)
        {
            var 效果 = 获取效果(效果ID);
            if (效果 != null)
            {
                技能.效果列表.Add(效果);
            }
        }
    }

    /// <summary>
    /// 从游戏元素执行技能
    /// </summary>
    public async Task<技能执行结果> 执行技能(战斗单位 施法者, 游戏元素 技能元素, List<战斗单位> 目标列表, 战斗管理器 战斗管理器)
    {
        // 从游戏元素创建临时技能配置
        var 技能配置 = new 技能配置
        {
            名称 = 技能元素.名称,
            描述 = 技能元素.描述,
            图标 = 技能元素.图标,
            目标类型 = 技能元素.目标类型,
            元素类型 = 技能元素.元素类型,
            消耗魔法值 = 技能元素.消耗魔法值,
            冷却时间 = 技能元素.冷却时间,
            效果ID列表 = new List<Guid>(技能元素.效果ID列表),
            效果列表 = new List<技能效果>(技能元素.效果列表)
        };

        // 检查魔法值
        if (施法者.当前魔法值 < 技能配置.消耗魔法值)
        {
            return 技能执行结果.失败("魔法值不足");
        }

        // 检查目标有效性
        if (!验证目标有效性(技能配置.目标类型, 目标列表, 施法者))
        {
            return 技能执行结果.失败("目标选择无效");
        }

        // 消耗魔法值
        施法者.当前魔法值 -= 技能配置.消耗魔法值;

        // 确保技能效果已加载
        if (技能配置.效果列表.Count == 0 && 技能配置.效果ID列表.Any())
        {
            加载技能效果(技能配置);
        }

        // 应用立即触发的效果
        foreach (var 效果 in 技能配置.效果列表.Where(e => e.触发时机 == 效果触发时机.立即触发))
        {
            if (new Random().NextDouble() <= 效果.触发概率)
            {
                效果.应用效果(施法者, 目标列表, 技能配置, 战斗管理器);
            }
        }

        // 发布技能使用事件
        await 战斗管理器.事件总线.发布事件(new 技能使用事件
        {
            施法者 = 施法者,
            技能名称 = 技能配置.名称,
            目标列表 = 目标列表
        });

        return 技能执行结果.成功();
    }

    /// <summary>
    /// 执行技能（保持向后兼容）
    /// </summary>
    public async Task<技能执行结果> 执行技能(战斗单位 施法者, string 技能名称, List<战斗单位> 目标列表, 战斗管理器 战斗管理器)
    {
        var 技能配置 = 获取技能配置(技能名称);
        if (技能配置 == null)
        {
            return 技能执行结果.失败($"技能{技能名称}不存在");
        }

        // 检查魔法值
        if (施法者.当前魔法值 < 技能配置.消耗魔法值)
        {
            return 技能执行结果.失败("魔法值不足");
        }

        // 检查目标有效性
        if (!验证目标有效性(技能配置.目标类型, 目标列表, 施法者))
        {
            return 技能执行结果.失败("目标选择无效");
        }

        // 消耗魔法值
        施法者.当前魔法值 -= 技能配置.消耗魔法值;

        // 确保技能效果已加载
        if (技能配置.效果列表.Count == 0)
        {
            加载技能效果(技能配置);
        }

        // 应用立即触发的效果
        foreach (var 效果 in 技能配置.效果列表.Where(e => e.触发时机 == 效果触发时机.立即触发))
        {
            if (new Random().NextDouble() <= 效果.触发概率)
            {
                效果.应用效果(施法者, 目标列表, 技能配置, 战斗管理器);
            }
        }

        // 发布技能使用事件
        await 战斗管理器.事件总线.发布事件(new 技能使用事件
        {
            施法者 = 施法者,
            技能名称 = 技能名称,
            目标列表 = 目标列表
        });

        return 技能执行结果.成功();
    }

    /// <summary>
    /// 验证目标选择是否符合技能要求
    /// </summary>
    private bool 验证目标有效性(技能目标类型 目标类型, List<战斗单位> 目标列表, 战斗单位 施法者)
    {
        if (目标列表.Count == 0) return false;

        switch (目标类型)
        {
            case 技能目标类型.自身:
                return 目标列表.Count == 1 && 目标列表[0] == 施法者;

            case 技能目标类型.友方单体:
                return 目标列表.Count == 1 && 目标列表[0].单位类型 == 施法者.单位类型;

            case 技能目标类型.敌方单体:
                return 目标列表.Count == 1 && 目标列表[0].单位类型 != 施法者.单位类型;

            case 技能目标类型.友方群体:
                return 目标列表.All(t => t.单位类型 == 施法者.单位类型);

            case 技能目标类型.敌方群体:
                return 目标列表.All(t => t.单位类型 != 施法者.单位类型);

            default:
                return false;
        }
    }

    /// <summary>
    /// 获取所有已注册技能
    /// </summary>
    public List<技能配置> 获取所有技能()
    {
        return [.. _技能配置字典.Values];
    }

    /// <summary>
    /// 获取所有已注册效果
    /// </summary>
    public List<技能效果> 获取所有效果()
    {
        return [.. _效果字典.Values];
    }
}

// 技能执行结果类
public class 技能执行结果
{
    public bool 是否成功 { get; set; }
    public string 消息 { get; set; } = string.Empty;
    public int 消耗魔法值 { get; set; }

    public static 技能执行结果 成功(string 消息 = "")
    {
        return new 技能执行结果 { 是否成功 = true, 消息 = 消息 };
    }

    public static 技能执行结果 失败(string 消息)
    {
        return new 技能执行结果 { 是否成功 = false, 消息 = 消息 };
    }
}